home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / agrep / preprocess.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  8KB  |  216 lines

  1. /* Copyright (c) 1991 Sun Wu and Udi Manber.  All Rights Reserved. */
  2. /* substitute metachar with special symbol                               */
  3. /* if regularr expression, then set flag REGEX                           */
  4. /* if REGEX and MULTIPAT then report error message,                      */
  5. /* -w only for single word pattern. If WORDBOUND & MULTIWORD error       */
  6. /* process start of line, endof line symbol,                             */
  7. /* process -w WORDBOUND option, append special symbol at begin&end of    */
  8. /* process -d option before this routine                                 */
  9. /* the delimiter pattern is in D_pattern (need to end with '; ')          */
  10. /* if '-t' (suggestion: how about -B) the pattern is passed to sgrep     */
  11. /* and doesn't go here                                                   */
  12. /* in that case, -d is ignored? or not necessary                         */
  13. /* upon return, Pattern contains the pattern to be processed by maskgen  */
  14. /* D_pattern contains transformed D_pattern                              */
  15.    
  16. #include "agrep.h"
  17.   
  18. extern int SIMPLEPATTERN, WHOLELINE, REGEX, RE_ERR, DELIMITER, TAIL, WORDBOUND;
  19. extern int HEAD;
  20. extern CHAR Progname[];
  21. extern int D_length;
  22. extern int table[WORD][WORD];
  23.   
  24. preprocess(D_pattern, Pattern)   /* need two parameters  */
  25. CHAR *D_pattern, *Pattern;
  26. {
  27.   CHAR temp[Maxline], *r_pat, *old_pat;  /* r_pat for r.e. */
  28.   CHAR old_D_pat[MaxDelimit];
  29.   int i, j=0, rp=0, m, t=0, partitions, num_pos, ANDON = 0;
  30.   int d_end ;  
  31.   int IN_RANGE=0, EVEN=0, OR_AND=0;
  32.   old_pat = Pattern; /* to remember the starting position */
  33.   m = strlen(Pattern);
  34.   for(i=0; i< m; i++) {
  35.       if(Pattern[i] == '\\') i++;
  36.       else if(Pattern[i] == '|' || Pattern[i] == '*' ) REGEX = ON;   
  37.   }
  38.   r_pat = (CHAR *) malloc(strlen(Pattern)+2*strlen(D_pattern));
  39.   strcpy(temp, D_pattern);
  40.   d_end = t = strlen(temp);  /* size of D_pattern, including '; ' */
  41.   if (WHOLELINE) { temp[t++] = LANGLE; 
  42.                    temp[t++] = NNLINE; 
  43.                    temp[t++] = RANGLE;
  44.                    temp[t] = '\0';
  45.                    strcat(temp, Pattern);
  46.                    m = strlen(temp);
  47.                    temp[m++] = LANGLE; 
  48.                    temp[m++] = '\n'; 
  49.                    temp[m++] = RANGLE; 
  50.                    temp[m] = '\0';  }
  51.   else {
  52.      if (WORDBOUND) { temp[t++] = LANGLE; 
  53.                       temp[t++] = WORDB; 
  54.                       temp[t++] = RANGLE;
  55.                       temp[t] = '\0'; }
  56.      strcat(temp, Pattern);
  57.      m = strlen(temp);
  58.      if (WORDBOUND) { temp[m++] = LANGLE; 
  59.                       temp[m++] = WORDB; 
  60.                       temp[m++] = RANGLE; }
  61.      temp[m] = '\0';
  62.   }
  63.         /* now temp contains augmented pattern , m it's size */
  64.  
  65.   D_length = 0;
  66.   for (i=0, j=0; i< d_end-2; i++) {
  67.       switch(temp[i]) 
  68.       {
  69.          case '\\' : i++; 
  70.                      Pattern[j++] = temp[i];
  71.                      old_D_pat[D_length++] = temp[i];
  72.                      break;
  73.          case '<'  : Pattern[j++] = LANGLE;
  74.                      break;
  75.          case '>'  : Pattern[j++] = RANGLE;
  76.                      break;
  77.          case '^'  : Pattern[j++] = '\n';
  78.                      old_D_pat[D_length++] = temp[i];
  79.                      break;
  80.          case '$'  : Pattern[j++] = '\n';
  81.                      old_D_pat[D_length++] = temp[i];
  82.                      break;
  83.          default  :  Pattern[j++] = temp[i];
  84.                      old_D_pat[D_length++] = temp[i];
  85.                      break;
  86.      }
  87.   }
  88.   if(D_length > MAXDELIM) {
  89.      fprintf(stderr, "%s: delimiter pattern too long\n", Progname);
  90.      exit(2);
  91.   }
  92.   Pattern[j++] = ANDPAT;
  93.   old_D_pat[D_length] = '\0';
  94.   strcpy(D_pattern, old_D_pat);
  95.   D_length++;
  96. /*
  97.   Pattern[j++] = ' ';
  98. */
  99.   Pattern[j] = '\0';
  100.   rp = 0; 
  101.   if(REGEX) {
  102.       r_pat[rp++] = '.';    /* if REGEX: always append '.' in front */
  103.       r_pat[rp++] = '(';
  104.       Pattern[j++] = NOCARE;
  105.       HEAD = ON;
  106.   }
  107.   for (i=d_end; i < m ; i++)
  108.   {
  109.        switch(temp[i]) 
  110.        {
  111.            case '\\': i++;  Pattern[j++] = temp[i]; 
  112.                       r_pat[rp++] = 'o';   /* the symbol doesn't matter */
  113.                       break;
  114.            case '#':  if(REGEX) {
  115.                          Pattern[j++] = NOCARE;
  116.                          r_pat[rp++] = '.';
  117.                          r_pat[rp++] = '*';
  118.                          break; }
  119.                       Pattern[j++] = WILDCD;
  120.                       break; 
  121.            case '(':  Pattern[j++] = LPARENT; 
  122.                       r_pat[rp++] = '(';     
  123.                       break;
  124.            case ')':  Pattern[j++] = RPARENT; 
  125.                       r_pat[rp++] = ')'; 
  126.                       break;
  127.            case '[':  Pattern[j++] = LRANGE;  
  128.                       r_pat[rp++] = '[';
  129.                       IN_RANGE = ON;
  130.                       break;
  131.            case ']':  Pattern[j++] = RRANGE;  
  132.                       r_pat[rp++] = ']'; 
  133.               IN_RANGE = OFF;
  134.                       break;
  135.            case '<':  Pattern[j++] = LANGLE;  
  136.                       break;
  137.            case '>':  Pattern[j++] = RANGLE;  
  138.                       break;
  139.            case '^':  if (temp[i-1] == '[') Pattern[j++] = NOTSYM;
  140.                       else Pattern[j++] = '\n';
  141.                       r_pat[rp++] = '^';
  142.                       break;
  143.            case '$':  Pattern[j++] = '\n'; 
  144.                       r_pat[rp++] = '$';
  145.                       break;
  146.            case '.':  Pattern[j++] = NOCARE;
  147.                       r_pat[rp++] = '.';
  148.                       break;
  149.            case '*':  Pattern[j++] = STAR; 
  150.                       r_pat[rp++] = '*';
  151.                       break;
  152.            case '|':  Pattern[j++] = ORSYM; 
  153.                       r_pat[rp++] = '|';
  154.                       break;
  155.            case ',':  Pattern[j++] = ORPAT;  
  156.                       RE_ERR = ON; 
  157.                       break;
  158.            case ';':  if(ANDON) RE_ERR = ON; 
  159.                       Pattern[j++] = ANDPAT;
  160.                       ANDON = ON;
  161.                       break;
  162.            case '-':  if(IN_RANGE) {
  163.                           Pattern[j++] = HYPHEN; 
  164.                           r_pat[rp++] = '-';
  165.                       }
  166.                       else { 
  167.                           Pattern[j++] = temp[i];
  168.                           r_pat[rp++] = temp[i];
  169.                       }  
  170.                       break;
  171.            case NNLINE :
  172.                       Pattern[j++] = temp[i];
  173.                       r_pat[rp++] = 'N';
  174.                       break;
  175.            default:   Pattern[j++] = temp[i]; 
  176.                       r_pat[rp++] = temp[i];
  177.                       break;
  178.       }
  179.   }
  180.   if(REGEX) {           /* append ').' at end of regular expression */
  181.       r_pat[rp++] = ')';
  182.       r_pat[rp++] = '.';
  183.       Pattern[j++] = NOCARE;
  184.       TAIL = ON;
  185.   }
  186.   Pattern[j] = '\0'; 
  187.   m = j;
  188.   r_pat[rp] = '\0'; 
  189.   if(REGEX)
  190.   {  
  191.      if(DELIMITER || WORDBOUND)  {
  192.           fprintf(stderr, "%s: -d or -w option is not supported for this pattern\n", Progname);
  193.           exit(2);
  194.      }
  195.      if(RE_ERR) {
  196.         fprintf(stderr, "%s: illegal regular expression\n", Progname);
  197.         exit(2);
  198.      }
  199.      while(*Pattern != NOCARE && m-- > 0) Pattern++;  /* poit to . */
  200.      num_pos = init(r_pat, table);
  201.      if(num_pos <= 0) {
  202.          fprintf(stderr, "%s: illegal regular expression\n", Progname);
  203.          exit(2);
  204.      }
  205.      if(num_pos > 30) {
  206.         fprintf(stderr, "%s: regular expression too long\n", Progname);
  207.         exit(2);
  208.      }
  209.   strcpy(old_pat, Pattern); /* do real change to the Pattern to be returned */
  210.   return;
  211.   } /* if regex */
  212.  
  213.   return;
  214. }
  215.  
  216.